package com.ichi2.anki.pj2;

import android.app.Activity;

import com.ichi2.anki.DeckPicker;
import com.ichi2.anki.R;

import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.text.SimpleDateFormat;
import java.util.Date;

import androidx.test.espresso.action.ViewActions;
import androidx.test.espresso.matcher.ViewMatchers;
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;

import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.clearText;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard;
import static androidx.test.espresso.action.ViewActions.longClick;
import static androidx.test.espresso.action.ViewActions.pressMenuKey;
import static androidx.test.espresso.action.ViewActions.scrollTo;
import static androidx.test.espresso.action.ViewActions.typeText;
import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.containsString;


/**
 * Basic tests showcasing simple view matchers and actions like {@link ViewMatchers#withId},
 * {@link ViewActions#click} and {@link ViewActions#typeText}.
 * <p>
 * Note that there is no need to tell Espresso that a view is in a different {@link Activity}.
 * 连接模拟器：nox_adb.exe connect 127.0.0.1:62001
 */
@RunWith(AndroidJUnit4.class)
@LargeTest
public class DeckPickerTest {
    @Rule
    public ActivityScenarioRule<DeckPicker> activityScenarioRule = new ActivityScenarioRule<>(DeckPicker.class);

    /**
     * 新增测试数据的前缀
     */
    String test = "aaaa";


    /**
     * 点击刷新显示登录
     */
    @Test
    public void login() {
        onView(withId(R.id.action_sync)).perform(click());
        onView(withId(R.id.md_root)).check(matches(isDisplayed()));
        onView(withId(R.id.md_button_positive)).perform(click());
        onView(withId(R.id.MyAccountLayout)).check(matches(isDisplayed()));
        onView(withId(R.id.toolbar)).perform(ViewActions.pressBack());
        onView(withId(R.id.action_sync)).perform(click());
        onView(withId(R.id.md_button_negative)).perform(click());
        onView(withId(R.id.md_root)).check(doesNotExist());
    }


    /**
     * 创建 filtered deck
     */
    @Test
    public void create_deck() {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
        String date = df.format(new Date());

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Create filtered deck")).perform(click());
        onView(withId(R.id.md_input_message)).perform(clearText(), typeText("deck_test" + date));
        onView(withId(R.id.md_button_positive)).perform(click());
        onView(withContentDescription("Navigate up")).perform(click());
        // 删除
        onView(withText("deck_test" + date)).perform(longClick());
        onView(withText("Delete deck")).perform(longClick());
        onView(withText("Delete")).perform(click());

        onView(withText("deck_test" + date)).check(doesNotExist());
    }


    /**
     * check database
     */
    @Test
    public void check_database() {
        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Check database")).perform(click());
        onView(withId(R.id.md_button_positive)).perform(click());
        onView(withText("Database checked")).check(matches(isDisplayed()));
    }


    /**
     * 查看empty card
     */
    @Test
    public void empty_card() {
        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Empty cards")).perform(click());
        onView(withText("No empty cards")).check(matches(isDisplayed()));
    }


    /**
     * 管理笔记类型
     */
    @Test
    public void manage_note_type() {
        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Manage note types")).perform(click());
        onView(withId(R.id.note_type_browser_list)).check(matches(isDisplayed()));
        // 添加笔记类型
        onView(withContentDescription("Add note type")).perform(click());
        onView(withText("Add: Basic")).perform(click());
        onView(withText("OK")).perform(click());
        onView(withText("OK")).perform(click());
        onView(withText("Basic")).perform(click());
        onView(withContentDescription("Add field")).perform(click());
        onView(withText("OK")).perform(click());
        onView(withText("field")).check(doesNotExist());
    }


    /**
     * 导入
     */
    @Test
    public void import_test() {
        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Import")).perform(click());
        onView(withText("Deck package (.apkg)")).check(matches(isDisplayed()));
    }


    /**
     * 导出
     */
    @Test
    public void export_test() {
        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Export collection")).perform(click());
        onView(withText("Export")).check(matches(isDisplayed()));
    }


    /**
     * 点击牌组，新增卡片,学习卡片
     */
    @Test
    public void add_deck_card() {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
        String date = df.format(new Date());

        onView(withId(R.id.fab_main)).perform(click());
        onView(withText("Create deck")).perform(click());
        onView(withId(R.id.md_input_message)).perform(typeText(test + "adeck_test" + date));
        onView(withId(R.id.md_button_positive)).perform(click());
        onView(withText(test + "adeck_test" + date)).perform(click());
        onView(withId(R.id.snackbar_action)).perform(click());
        onView(withContentDescription("Front")).perform(click(), typeText("Front1_" + date));
        onView(withContentDescription("Back")).perform(click(), typeText("Back_1" + date), closeSoftKeyboard());
        onView(withContentDescription("Save")).perform(click());
        onView(withContentDescription("Navigate up")).perform(click());

        onView(withText(test + "adeck_test" + date)).perform(click());


        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Enable whiteboard")).perform(click());

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Clear whiteboard")).perform(click());

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Whiteboard editor")).perform(click());

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Save whiteboard")).perform(click());

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Disable whiteboard")).perform(click());

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Enable whiteboard")).perform(click());

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Enable stylus mode")).perform(click());

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Disable stylus mode")).perform(click());

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Disable whiteboard")).perform(click());

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Edit note")).perform(click());
        onView(withContentDescription("Front")).perform(click(), clearText(), typeText("edit_" + date));
        onView(withContentDescription("Save")).perform(click());


        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Edit note")).perform(click());
        // 复制笔记
        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Copy note")).perform(click());
        // 修改字体大小
        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Font size")).perform(click());
        onView(withText("Cancel")).perform(click());
        // 修改其他配置
        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Capitalize sentences")).perform(click());

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Show toolbar")).perform(click());
        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Scroll toolbar")).perform(click());
        // 点击预览
        onView(withContentDescription("Preview")).perform(click());

        onView(withId(R.id.toolbar)).perform(ViewActions.pressBack());
        onView(withId(R.id.toolbar)).perform(ViewActions.pressBack());
        onView(withText("OK")).perform(click());
        onView(withId(R.id.toolbar)).perform(ViewActions.pressBack());

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Edit tags")).perform(click());
        onView(withText("OK")).perform(click());

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Mark note")).perform(click());

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Unmark note")).perform(click());

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Reschedule")).perform(click());
        onView(withText("Reset progress")).perform(click());
        onView(withText("OK")).perform(click());

        onView(withId(R.id.toolbar)).perform(pressMenuKey());
        onView(withText("Replay audio")).perform(click());

        // 展示答案
        onView(withId(R.id.flashcard_layout_flip)).perform(click());

        onView(withText("Easy")).perform(click());
        onView(withText("Easy")).check(doesNotExist());
    }


    /**
     * 下载共享卡片
     */
    @Test
    public void get_shared() {
        onView(withId(R.id.fab_main)).perform(click());
        onView(withText("Get shared decks")).perform(click());
        onView(withText("Download deck")).check(matches(isDisplayed()));
    }


    /**
     * 新增卡片
     */
    @Test
    public void add_card() {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
        String date = df.format(new Date());

        onView(withId(R.id.fab_main)).perform(click());
        onView(withText("Create deck")).perform(click());
        onView(withId(R.id.md_input_message)).perform(typeText(test + "adeck_test" + date));
        onView(withId(R.id.md_button_positive)).perform(click());

        onView(withId(R.id.fab_main)).perform(click());
        onView(withText("Add")).perform(click());
        onView(withId(R.id.note_type_spinner)).perform(click());
        onView(withText("Basic")).perform(click());
        onView(withId(R.id.note_deck_spinner)).perform(click());
        onView(withText(test + "adeck_test" + date)).perform(click());
        onView(withContentDescription("Front")).perform(click(), typeText("Front_" + date));
        onView(withContentDescription("Back")).perform(click(), typeText("Back_" + date), closeSoftKeyboard());
        onView(withContentDescription("Save")).perform(click());
        onView(withText("1 card added")).check(matches(isDisplayed()));
    }


    /**
     * 长按牌组显示菜单
     */
    @Test
    public void long_click() {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
        String date = df.format(new Date());

        onView(withId(R.id.fab_main)).perform(click());
        onView(withText("Create deck")).perform(click());
        onView(withId(R.id.md_input_message)).perform(typeText(test + "deck_test" + date));
        onView(withId(R.id.md_button_positive)).perform(click());
        onView(withText(test + "deck_test" + date)).perform(scrollTo(), longClick());
        onView(withId(R.id.md_recyclerview_content)).check(matches(isDisplayed()));
    }


    /**
     * 长按牌组显示菜单后新增卡片
     */
    @Test
    public void long_click_add() {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
        String date = df.format(new Date());

        onView(withId(R.id.fab_main)).perform(click());
        onView(withText("Create deck")).perform(click());
        onView(withId(R.id.md_input_message)).perform(typeText(test + "aadeck_test" + date));
        onView(withId(R.id.md_button_positive)).perform(click());
        onView(withText(test + "aadeck_test" + date)).perform(scrollTo(), longClick());
        onView(withText("Add")).perform(click());
        onView(withContentDescription("Front")).check(matches(isDisplayed()));
    }


    /**
     * 长按牌组显示菜单后浏览卡片
     */
    @Test
    public void long_click_browser() {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
        String date = df.format(new Date());

        onView(withId(R.id.fab_main)).perform(click());
        onView(withText("Create deck")).perform(click());
        onView(withId(R.id.md_input_message)).perform(typeText(test + "adeck_test" + date));
        onView(withId(R.id.md_button_positive)).perform(click());
        onView(withText(test + "adeck_test" + date)).perform(scrollTo(), longClick());
        onView(withText("Browse cards")).perform(click());
        onView(withId(R.id.card_browser_list)).check(matches(isDisplayed()));
    }


    /**
     * 长按牌组显示菜单后新建子牌组
     */
    @Test
    public void long_click_sub() {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
        String date = df.format(new Date());

        onView(withId(R.id.fab_main)).perform(click());
        onView(withText("Create deck")).perform(click());
        onView(withId(R.id.md_input_message)).perform(typeText(test + "deck_test" + date));
        onView(withId(R.id.md_button_positive)).perform(click());
        onView(withText(test + "deck_test" + date)).perform(scrollTo(), longClick());
        onView(withText("Create subdeck")).perform(click());
        onView(withId(R.id.md_input_message)).perform(typeText("subdeck_test" + date));
        onView(withId(R.id.md_button_positive)).perform(click());
        onView(withText("subdeck_test" + date)).check(matches(isDisplayed()));
    }


    /**
     * 长按牌组显示菜单后重命名
     */
    @Test
    public void long_click_rename() {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
        String date = df.format(new Date());

        onView(withId(R.id.fab_main)).perform(click());
        onView(withText("Create deck")).perform(click());
        onView(withId(R.id.md_input_message)).perform(typeText(test + "deck_test" + date));
        onView(withId(R.id.md_button_positive)).perform(click());
        onView(withText(test + "deck_test" + date)).perform(scrollTo(), longClick());
        onView(withText("Rename deck")).perform(click());
        onView(withId(R.id.md_input_message)).perform(clearText(), typeText(test + "arename" + date));
        onView(withId(R.id.md_button_positive)).perform(click());
        onView(withText(test + "arename" + date)).perform(scrollTo()).check(matches(isDisplayed()));
    }


    /**
     * 长按牌组显示菜单后选项
     */
    @Test
    public void long_click_option() {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
        String date = df.format(new Date());

        onView(withId(R.id.fab_main)).perform(click());
        onView(withText("Create deck")).perform(click());
        onView(withId(R.id.md_input_message)).perform(typeText(test + "deck_test" + date));
        onView(withId(R.id.md_button_positive)).perform(click());
        onView(withText(test + "deck_test" + date)).perform(longClick());
        onView(withText("Deck options")).perform(click());
        onView(withText(containsString("Options for"))).check(matches(isDisplayed()));
    }


    /**
     * 长按牌组显示菜单后学习
     */
    @Test
    public void long_click_study() {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
        String date = df.format(new Date());

        onView(withId(R.id.fab_main)).perform(click());
        onView(withText("Create deck")).perform(click());
        onView(withId(R.id.md_input_message)).perform(typeText(test + "adeck_test" + date));
        onView(withId(R.id.md_button_positive)).perform(click());
        onView(withText(test + "adeck_test" + date)).perform(scrollTo(), longClick());
        onView(withText("Custom study")).perform(click());
        onView(withText("Custom study")).check(matches(isDisplayed()));
    }


    /**
     * 长按牌组显示菜单后删除牌组
     */
    @Test
    public void long_click_delete() {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
        String date = df.format(new Date());

        onView(withId(R.id.fab_main)).perform(click());
        onView(withText("Create deck")).perform(click());
        onView(withId(R.id.md_input_message)).perform(typeText(test + "adeck_test" + date));
        onView(withId(R.id.md_button_positive)).perform(click());
        onView(withText(test + "adeck_test" + date)).perform(scrollTo(), longClick());
        onView(withText("Delete deck")).perform(click());

        onView(withId(R.id.list)).check(doesNotExist());
    }
}
